﻿
using System;
using System.IO;
using System.Reflection;
using ActiproSoftware.SyntaxEditor;
using ActiproSoftware.SyntaxEditor.Addons.Dynamic;

namespace S3.WMDSLEditor.Client
{
    public class WmdslLanguages
    {
        /// <summary>
        /// Loads two languages and creates a state transition from XML to C# within <c>style</c> tags.
        /// </summary>
        public static SyntaxLanguage CreateScriptXmlToSqlLanguage()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Stream streamXml = null;
            Stream streamSql = null;
            
            streamSql = assembly.GetManifestResourceStream("S3.WMDSLEditor.Client.WmdslEditor.SQL.xml");
            streamXml = assembly.GetManifestResourceStream("S3.WMDSLEditor.Client.WmdslEditor.XML.xml");


            // Load the two languages
            DynamicSyntaxLanguage language = DynamicSyntaxLanguage.LoadFromXml(streamXml, 0);
            DynamicSyntaxLanguage sqlLanguage = DynamicSyntaxLanguage.LoadFromXml(streamSql, 0);

            // Update the example text
            language.ExampleText = "<tagblock>\r\n" +
                "\t<!-- This script block transitions to C# language -->\r\n" +
                "\t<Expression>\r\n" +
                "\t\t// C# comment\r\n" +
                "\t\tfor (int i = 0; i < 10; i++) {\r\n" +
                "\t\t}\r\n" +
                "\t</Expression>\r\n" +
                "</tagblock>\r\n";

            // Mark that updating is starting
            language.IsUpdating = true;
            sqlLanguage.IsUpdating = true;

            // Create a new lexical state
            DynamicLexicalState lexicalState = new DynamicLexicalState(0, "ScriptStartTagState");
            lexicalState.DefaultTokenKey = "ScriptStartTagDefaultToken";
            lexicalState.DefaultHighlightingStyle = language.HighlightingStyles["TagNameStyle"];
            lexicalState.ChildLexicalStates.Add(language.LexicalStates["StartTagAttributeState"]);
            language.LexicalStates.Add(lexicalState);

            // Add the new lexical state at the beginning of the child states...
            // Remember that with an NFA regular expression, the first match is taken...
            // So since a < scope pattern is already in place, we must insert the new one before it
            language.LexicalStates["DefaultState"].ChildLexicalStates.Insert(0, lexicalState);

            // Create a lexical scope with a lexical state transition
            DynamicLexicalScope lexicalScope = new DynamicLexicalScope();
            lexicalState.LexicalScopes.Add(lexicalScope);
            lexicalScope.StartLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "StartTagStartToken",
                    language.HighlightingStyles["TagDelimiterStyle"], @"<", "Expression");
            lexicalScope.EndLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Regex, "StartTagEndToken",
                    language.HighlightingStyles["TagDelimiterStyle"], @"/? >");
            DynamicLexicalScope transitionLexicalScope = new DynamicLexicalScope();
            transitionLexicalScope.EndLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "EndTagStartToken",
                    language.HighlightingStyles["TagDelimiterStyle"], @"</", "Expression");
            lexicalScope.LexicalStateTransition = new LexicalScopeLexicalStateTransition(sqlLanguage.LexicalStates["DefaultState"], transitionLexicalScope);

            // Mark that updating is complete (since linking is complete, the flag setting 
            //   will filter from the XML language into the C# language)
            language.IsUpdating = false;

            return language;
        }

        //public static void LoadLanguageDefinition(Language language, ref Document document)
        //{
        //    try
        //    {
        //        // Get the Actipro language filename base
        //        string filenameBase = Program.DynamicLexersPath + "WmdslEditor." + language;

        //        document.LoadLanguageFromXml(filenameBase + ".xml", 0);
        //    }
        //    catch (Exception)
        //    {
        //        document.ResetLanguage();
        //    }
        //}

        public static void LoadLanguageDefinitionFromResource(Language language, ref Document document)
        {
            try
            {
                Assembly assembly = Assembly.GetExecutingAssembly();
                Stream stream = null;

                switch (language)
                {
                    case Language.SQL:
                        stream = assembly.GetManifestResourceStream("S3.WMDSLEditor.Client.WmdslEditor.SQL.xml");
                        break;
                    case Language.XML:
                        stream = assembly.GetManifestResourceStream("S3.WMDSLEditor.Client.WmdslEditor.XML.xml");
                        break;
                }

                if(stream != null)
                {
                    document.LoadLanguageFromXml(stream, 0);
                }
            }
            catch (Exception)
            {
                document.ResetLanguage();
            }
        }

        ///// <summary>
        ///// Loads a language definition into the editor.
        ///// </summary>
        ///// <param name="language">A <c>Language</c> specifying the type of language to load.</param>
        //private void LoadLanguageDefinition(Language language)
        //{
        //    try
        //    {
        //        // Get the Actipro language filename base
        //        string filenameBase = Program.DynamicLexersPath + "ActiproSoftware." + language;

        //        //MessageBox.Show(filenameBase);

        //        syntaxEditor.Document.LoadLanguageFromXml(filenameBase + ".xml", 0);

        //        if (language == Language.None)
        //        {
        //            syntaxEditor.Document.Outlining.Mode = OutliningMode.None;
        //        }
        //        else if (_lastLanguageWasPlainText)
        //        {
        //            syntaxEditor.Document.Outlining.Mode = OutliningMode.Automatic;
        //            syntaxEditor.Document.SemanticParsingEnabled = (language != Language.None);
        //            syntaxEditor.Document.LexicalParsingEnabled = (language != Language.None);
        //            _lastLanguageWasPlainText = (language == Language.None);
        //        }
        //    }
        //    catch (Exception)
        //    {
        //        syntaxEditor.Document.ResetLanguage();
        //    }
        //}

        //private SyntaxLanguage GetLanguageDefinition(Language language, bool lastLanguageWasPlainText)
        //{
        //    Document doc =  new Document();

        //    try
        //    {
        //        string filenameBase = Program.DynamicLexersPath + "WmdslEditor." + language;

        //        doc.LoadLanguageFromXml(filenameBase + ".xml", 0);

        //        //if (language == Language.None)
        //        //{
        //        //    syntaxEditor.Document.Outlining.Mode = OutliningMode.None;
        //        //}
        //        //else if (lastLanguageWasPlainText)
        //        //{
        //        //    syntaxEditor.Document.Outlining.Mode = OutliningMode.Automatic;
        //        //    syntaxEditor.Document.SemanticParsingEnabled = (language != Language.None);
        //        //    syntaxEditor.Document.LexicalParsingEnabled = (language != Language.None);
        //        //    lastLanguageWasPlainText = (language == Language.None);
        //        //}
        //    }
        //    catch (Exception)
        //    {
        //        //syntaxEditor.Document.ResetLanguage();
        //    }

        //    return doc.Language;
        //}
    }
}
